#!/usr/bin/python3
# -*- coding:UTF-8 -*-

#作品名称：冰枫蓝叶聊天女仆 - 井字棋游戏
#作者：Loveaabb <loveaabbcraft@163.com>
#许可证：GNU LGPL v3 or later
#后续更新：冰枫火灵X
'''
部分源代码参考自 Sunmer_days 的文章 https://blog.csdn.net/qq_39035741/article/details/77101765
'''
import random


class ticTacToe:
    # 井字棋模块

    def drawBoard(self, brd):
        # 在终端里画出棋盘
        print('\n\n\n')
        print('┌─┬─┬─┐')
        print('|' + brd[7] + '|' + brd[8] + '|' + brd[9] + '|')
        print('├─┼─┼─┤')
        print('|' + brd[4] + '|' + brd[5] + '|' + brd[6] + '|')
        print('├─┼─┼─┤')
        print('|' + brd[1] + '|' + brd[2] + '|' + brd[3] + '|')
        print('└─┴─┴─┘')

    def playerSide(self):
        # 玩家选棋子
        while True:
            ltr = input('请选择你的棋子(输入O或X): ')
            if ltr == 'X' or ltr == 'x':
                return 'X', 'O'
            elif ltr == 'O' or ltr == 'o':
                return 'O', 'X'
            else:
                print('请输入"X" 或 "O"')

    def move(self, brd, side, mov):
        # 落子
        brd[mov] = side

    def winner(self, brd, sd):
        # 判断某一方获胜
        return (brd[1] == sd and brd[2] == sd and brd[3] == sd) or (brd[4] == sd and brd[5] == sd and brd[6] == sd) or (
                    brd[7] == sd and brd[8] == sd and brd[9] == sd) or (
                           brd[1] == sd and brd[4] == sd and brd[7] == sd) or (
                           brd[2] == sd and brd[5] == sd and brd[8] == sd) or (
                           brd[3] == sd and brd[6] == sd and brd[9] == sd) or (
                           brd[1] == sd and brd[5] == sd and brd[9] == sd) or (
                           brd[3] == sd and brd[5] == sd and brd[7] == sd)

    def isSpaceEmpty(self, brd, mov):
        # 判断棋盘上某个位置是不是空的
        return brd[mov] == ' '

    def isBoardFull(self, brd):
        # 判断棋盘是否满了
        for i in range(1, 10):
            if self.isSpaceEmpty(brd, i):
                return False

        return True

    def randomMove(self, brd, plist):
        # 再棋盘内给定的位置中随机选取1个位置落子
        pmov = []
        for i in plist:
            if self.isSpaceEmpty(brd, i):
                pmov.append(i)

        if len(pmov) != 0:
            return random.choice(pmov)
        else:
            return None

    def cpBoard(self, brd):
        # 创建一个棋盘的副本给电脑用
        # 这样就不会影响到全局棋盘
        board = []

        for i in brd:
            board.append(i)

        return board

    def maidMove(self, brd, maidSide):
        if maidSide == 'X':
            playerSide = 'O'
        else:
            playerSide = 'X'

        # 以下是井字棋游戏的核心算法
        # 判断能否一步胜利
        for i in range(1, 10):
            cp = self.cpBoard(brd)

            if self.isSpaceEmpty(cp, i):
                self.move(cp, maidSide, i)

            if self.winner(cp, maidSide):
                return i

            # 判断能否堵死将要胜利的玩家
            for i in range(1, 10):
                cp = self.cpBoard(brd)
                if self.isSpaceEmpty(cp, i):
                    self.move(cp, playerSide, i)
                if self.winner(cp, playerSide):
                    return i

            # 在棋盘角落子
            mov = self.randomMove(brd, [1, 3, 7, 9])
            if mov != None:
                return mov

            # 在棋盘中心落子
            if self.isSpaceEmpty(brd, 5):
                return 5

            # 在棋盘边上落子
            return self.randomMove(brd, [2, 4, 6, 8])
            

    def startGame(self):
        print('让我们一起来玩井字棋吧！ ')
        ps, maidS = self.playerSide()
        brd = [' '] * 10

        while True:
            self.drawBoard(brd)

            if self.winner(brd, ps):
                print('你赢啦！主人好厉害ww')
                break

            if self.winner(brd, maidS):
                print('我赢了！好开心(｡◕ˇ∀ˇ◕)')
                break
                
            while True:
                print('\n棋盘每个格子的坐标和小键盘一致')
                move = int(input("请选择落子位置(输入1~9之间的整数): "))
                if move not in range(1, 10):
                    print('\n请输入有效的格子编号')
                    continue

                if not self.isSpaceEmpty(brd, move):
                    print('\n这个位置已被占用！')
                    continue
                    
                self.move(brd, ps, move)
                break

            if self.winner(brd, ps):
                self.drawBoard(brd)
                print('你赢啦！主人好厉害ww')
                break

            if self.winner(brd, maidS):
                self.drawBoard(brd)
                print('我赢了！好开心(｡◕ˇ∀ˇ◕)')
                break

            if self.isBoardFull(brd):
                self.drawBoard(brd)
                print('平局!')
                break

            maidmov = self.maidMove(brd, maidS)
            self.move(brd, maidS, maidmov)
